#' Maximum Absolute difference test 
#' 
#' 
#' @param m a matrix, each column contains an values of summary statistics for observed (the first column) and null communities (other columns)
#' @param alpha significant level of the global test
#' @param two_side indicate whether the test is two side or one side test
#' @param returnfpvalue a logical flag to indicate whether a very rough pvalue should be returned. if FALSE, just return whether the test is significant or not
#' @param obsadj a logical flag to indicate whether a adjusted observation by G+ should be return.
#' 
#' 

MAD=function(m,alpha=0.05,two_side=FALSE,retunfpvalue=TRUE,obsadj=TRUE){
  obs=m[,1]
  null=m[,-1]
  mean_null=apply(null,1,mean,na.rm=TRUE)
  sd_null=apply(null,1,sd,na.rm=TRUE)
  #absolute difference for simulation
  null_adjust=abs(null-mean_null)/sd_null
  sims_max=apply(null_adjust,2,max,na.rm=T)
  
  #difference for observation
  obs=(obs-mean_null)/sd_null
  
  if(two_side){
    Gplusi=round(alpha/2*(dim(m)[2]),0)
  }else{
    Gplusi=round(alpha*(dim(m)[2]),0)
  }
  
  if(Gplusi<1) Gplusi=1
  
  Gplus=sort(sims_max,decreasing = TRUE)[Gplusi]
  #maybe we need to return other things like Gplus for other usage
  if(max(abs(obs/Gplus),na.rm=T)>1){
    sig=TRUE
  }else{
    sig=FALSE
  }
  
  if(retunfpvalue){
    #sig=1-sum(max(abs(obs),na.rm=T)>sims_max)/(dim(m)[2])

    if(sig){
      #return a very rough estimated pvalue
      sig=alpha*0.1
    }else{
      sig=alpha*10
    }
  }
  
  obsadj=obs/Gplus;
  attr(sig,"obsadj")=obsadj
  
  return(sig)
}

